/******************************************************************************
* 文件名  ：bsp_timer.c
* 文件描述：
* 创建人  ：
* 日    期：
*          
   TIME3-CH3-PB0 PWM输出 
******************************************************************************/
#include "DRV_Timer3.h"


static uint16_t cp_duty=0;

//duty精度%0.1(千分之一),999表示99.9
//公式一：占空比(Dutyon) = (CCR/ARR)*1000
//公式二：CRR=Dutyon*ARR/1000
uint16_t Duty2CCR(uint16_t duty, uint16_t arr)
{
    return duty*arr/1000;
}
/*******************************************************************************
* Function Name  : void cp_pwm_init(void)
* Description    : CP PWM初始化
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void cp_pwm_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    /* 硬件时钟初始化 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);

    /* PWM CH3 PB0 端口初始化 */
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);  

    //公式一：时钟频率(system_clk=72M)/预分频(psc)/想要的pwm频率(freq=1K)=重装值(arr)
    //公式二：定时时间(T)=1/freq
    //公式三：T=arr*psc/system_clk
    //公式四：TIM3计数时钟=system_clk/psc
    //公式五：占空比(Dutyon) = (CCR/ARR)*100%
    //注意：arr和psc在设置的时候都要减一，因为在硬件上会自动加一
    //结果：psc=72,arr=1000,T=1ms,TIM3计数时钟=1M
    uint16_t ARR,PSC=72,CCR,Freq=1000;
    ARR=SystemCoreClock/PSC/Freq;
    //printf("=====>arr=%d,psc=%d\r\n",ARR,PSC);
    TIM_TimeBaseStructure.TIM_Period        = (ARR-1);       	    //当定时器从0计数到 TIM_Period+1 ，为一个定时周期
    TIM_TimeBaseStructure.TIM_Prescaler     = (PSC-1);	    	    //设置预分频
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;		//设置时钟分频系数
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;  	//向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    CCR=Duty2CCR(1000,ARR);//Capture Compare Register
    //printf("=====>CCR=%d\r\n");
    TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1;	        //配置为PWM模式1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//使能输出
    TIM_OCInitStructure.TIM_Pulse       = CCR;                      //设置初始PWM脉冲宽度70
    TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_Low;       //当定时器计数值小于比较值时为低电平

    TIM_OC3Init ( TIM3, &TIM_OCInitStructure );	 					//使能通道，通道几就是OCx，例如通道3就是TIM_OC3Init
    TIM_OC3PreloadConfig ( TIM3, TIM_OCPreload_Enable );			//使能预装载	
    TIM_ARRPreloadConfig(TIM3, ENABLE);			 					//使能TIM重载寄存器ARR

    TIM_Cmd(TIM3, ENABLE);
}

/*******************************************************************************
* Function Name  : cp_set_duty
* Description    : 设置占空比，千分之一精度
                   占空比(Dutyon) = (CCR/ARR)1000
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void cp_duty_set(uint16_t val)
{
    if(val<=CP_DUTY_1000)
    {
        TIM_SetCompare3(TIM3, val);
        cp_duty = val;
    }
}

/*******************************************************************************
* Function Name  : cp_duty_get
* Description    : 获取占空比
* Input          : None
* Output         : 占空比，千分之一精度
* Return         : 0.成功，非0失败
*******************************************************************************/
uint8_t cp_duty_get(uint16_t *pDuty)
{
    *pDuty = cp_duty;
    
    return 0;
}

/*******************************************************************************
* Function Name  : cp_duty_to_curr
* Description    : 根据占空比计算电流
* Input          : cp_duty-占空比，千分之一精度
* Output         : 电流，I=cp_duty*100*0.6, cp_duty为占空比
* Return         : None
1. 占空比为*10后的值，如53.3%,则输入533
2. 返回的电流值为*100后的值, 如:3198->31.98A
3. 转换公式: I=D*100*0.6, D为占空比
*******************************************************************************/
uint16_t cp_duty_to_curr(uint16_t cp_duty)
{
    return (cp_duty*6);
}

/*******************************************************************************
* Function Name  : cp_curr_to_duty
* Description    : 根据占空比计算电流
* Input          : curr-电流值，单位0.01A
* Output         : None
* Return         : 占空比，千分之一精度
1. 占空比为*10后的值，如53.3%,则输入533
2. 返回的电流值为*100后的值, 如:3198->31.98A
3. 转换公式: I=D*100*0.6, D为占空比
*******************************************************************************/
uint16_t cp_curr_to_duty(uint16_t curr)
{
    return (curr/6);
}
